﻿using System;
using System.Web.Mvc;
using DTcms.Common;
using System.Web;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Text;
using System.IO;
using System.Web.UI;

namespace DTcms.Web.Mvc.UI
{
    public partial class BaseController : Controller
    {
        protected internal Model.siteconfig config = new BLL.siteconfig().loadConfig();
        protected internal Model.userconfig uconfig = new BLL.userconfig().loadConfig();
        protected internal Model.sites site = new Model.sites();
        protected internal Model.site_channel site_model = new Model.site_channel();

        public BaseController()
        {
            //是否关闭网站
            if (config.webstatus == 0)
            {
                throw new HttpException(404, config.webclosereason);
            }
            //取得站点信息
            site = GetSiteModel();
        }

        #region 处理压缩HTML
        /// <summary>
        ///StringBuilder
        /// </summary>
        private StringBuilder _builder;

        /// <summary>
        ///HttpWriter
        /// </summary>
        private HttpWriter _output;

        /// <summary>
        /// 在执行Action的时候，就把需要的Writer存起来
        /// </summary>
        /// <param name="filterContext">上下文</param>
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (config.webgzip == 1)
            {
                _builder = new StringBuilder();
                StringWriter _writer = new StringWriter(_builder);
                HtmlTextWriter _htmlWriter = new HtmlTextWriter(_writer);
                _output = (HttpWriter)filterContext.RequestContext.HttpContext.Response.Output;
                filterContext.RequestContext.HttpContext.Response.Output = _htmlWriter;
                base.OnActionExecuting(filterContext);
            }
        }

        /// <summary>
        /// 在执行完成后，处理得到的HTML，并将他输出到前台
        /// </summary>
        /// <param name="filterContext"></param>
        protected override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            if (config.webgzip == 1)
            {
                var response = Utils.GzipHtml(_builder.ToString());
                _output.Write(response);
            }
        }
        #endregion

        #region 页面通用方法==========================================
        /// <summary>
        /// 返回站点信息
        /// </summary>
        public Model.sites GetSiteModel()
        {
            string requestDomain = System.Web.HttpContext.Current.Request.Url.Authority.ToLower(); //获得来源域名含端口号
            string requestPath = System.Web.HttpContext.Current.Request.RawUrl.ToLower(); //当前的URL地址
            string sitePath = GetSitePath(requestPath, requestDomain);
            Model.sites modelt = new Model.sites();
            try
            {
                modelt = SiteDomains.GetSiteDomains().SiteList.Find(p => p.build_path == sitePath);
            }
            catch (Exception)
            {
                throw new Exception("站点获取错误！");
            }
            return modelt;
        }

        /// <summary>
        /// 查找匹配的URL
        /// </summary>
        /// <param name="channel_id">频道ID</param>
        /// <param name="call_index">调用名</param>
        /// <param name="id">ID</param>
        /// <returns></returns>
        public string get_url_rewrite(int channel_id, string call_index, int id)
        {
            if (channel_id == 0)
            {
                return string.Empty;
            }
            string querystring = id.ToString();
            string channel_name = new BLL.site_channel().GetChannelName(channel_id);
            if (string.IsNullOrEmpty(channel_name))
            {
                return string.Empty;
            }
            if (!string.IsNullOrEmpty(call_index))
            {
                querystring = call_index;
            }
            BLL.url_rewrite bll = new BLL.url_rewrite();
            Model.url_rewrite model = bll.GetInfo(channel_name, "detail");
            if (model != null)
            {
                return linkurl(model.name, querystring);
            }
            return string.Empty;
        }

        /// <summary>
        /// 查找匹配的URL
        /// </summary>
        /// <param name="channel_id">频道ID</param>
        /// <param name="call_index">调用名</param>
        /// <param name="id">ID</param>
        /// <returns></returns>
        public string get_url_rewrite(string channel_name, string type, string call_index, int id)
        {
            string querystring = id.ToString();
            if (string.IsNullOrEmpty(channel_name))
            {
                return string.Empty;
            }
            if (!string.IsNullOrEmpty(call_index))
            {
                querystring = call_index;
            }
            BLL.url_rewrite bll = new BLL.url_rewrite();
            Model.url_rewrite model = bll.GetInfo(channel_name, type);
            if (model != null)
            {
                return linkurl(model.name, querystring);
            }
            return string.Empty;
        }

        /// <summary>
        /// 返回URL重写统一链接地址
        /// </summary>
        public string linkurl(string _key, params object[] _params)
        {
            Hashtable ht = new BLL.url_rewrite().GetList(); //获得URL配置列表
            Model.url_rewrite model = ht[_key] as Model.url_rewrite; //查找指定的URL配置节点

            //如果不存在该节点则返回空字符串
            if (model == null)
            {
                return string.Empty;
            }

            return linkurl(model, _params);
        }
        
        /// <summary>
        /// 返回URL重写统一链接地址(2017-08-14)
        /// </summary>
        public string linkurl(Model.url_rewrite model, params object[] _params)
        {
            string requestDomain = System.Web.HttpContext.Current.Request.Url.Authority.ToLower(); //获得来源域名含端口号
            string requestPath = System.Web.HttpContext.Current.Request.RawUrl.ToLower(); //当前的URL地址
            string linkStartString = GetLinkStartString(requestPath, requestDomain); //链接前缀

            //如果URL字典表达式不需要重写则直接返回
            if (model.url_rewrite_items.Count == 0)
            {
                //检查网站重写状态
                if (config.staticstatus > 0)
                {
                    if (_params.Length > 0)
                    {
                        return linkStartString + GetUrlExtension(model.page, config.staticextension) + string.Format("{0}", _params);
                    }
                    else
                    {
                        return linkStartString + GetUrlExtension(model.page, config.staticextension);
                    }
                }
                else
                {
                    if (_params.Length > 0)
                    {
                        return linkStartString + model.page + string.Format("{0}", _params);
                    }
                    else
                    {
                        return linkStartString + model.page;
                    }
                }
            }
            if (model.url_rewrite_items.Count == 1 && _params.Length > 0)
            {
                Model.url_rewrite_item item = model.url_rewrite_items[0];
                if (string.IsNullOrEmpty(item.querystring))
                {
                    //检查网站重写状态
                    if (config.staticstatus > 0)
                    {
                        return linkStartString + GetUrlExtension(item.path, config.staticextension) + string.Format("{0}", _params);
                    }
                    else
                    {
                        return linkStartString + item.path + string.Format("{0}", _params);
                    }
                }
            }
            //否则检查该URL配置节点下的子节点
            foreach (Model.url_rewrite_item item in model.url_rewrite_items)
            {
                //如果参数个数匹配
                if (IsUrlMatch(item, _params))
                {
                    //检查网站重写状态
                    if (config.staticstatus > 0)
                    {
                        return linkStartString + string.Format(GetUrlExtension(item.path, config.staticextension), _params);
                    }
                    else
                    {
                        string queryString = Regex.Replace(string.Format(item.path, _params), item.pattern, item.querystring, RegexOptions.None | RegexOptions.IgnoreCase);
                        if (queryString.Length > 0)
                        {
                            queryString = "?" + queryString;
                        }
                        return linkStartString + model.page + queryString;
                    }
                }
            }

            return string.Empty;
        }

        #region 2017-06-12添加
        /// <summary>
        /// 合并扩展参数
        /// </summary>
        /// <param name="url">URL地址</param>
        /// <param name="param">参数</param>
        /// <returns></returns>
        public string mergeurl(string url, string param)
        {
            if (!string.IsNullOrEmpty(url))
            {
                if (config.staticstatus > 0 || (config.staticstatus == 0 && url.EndsWith(".aspx")))
                {
                    url += "?" + param;
                }
                else
                {
                    url += "&" + param;
                }
            }
            return url;
        }

        /// <summary>
        /// 返回URL重写统一链接地址
        /// </summary>
        /// <param name="_key">调用名称</param>
        /// <param name="_call_index">调用名称</param>
        /// <param name="_id">文章ID</param>
        /// <returns></returns>
        public string queryurl(string _key, string call_index, object id)
        {
            if (string.IsNullOrEmpty(call_index))
            {
                return linkurl(_key, id);
            }
            return linkurl(_key, call_index);
        }

        /// <summary>
        /// 返回URL重写统一链接地址
        /// </summary>
        /// <param name="_key">调用名称</param>
        /// <param name="_url">链接地址</param>
        /// <param name="_call_index">调用名称</param>
        /// <param name="_id">文章ID</param>
        /// <returns></returns>
        public string queryurl(string _key, string url, string call_index, object id)
        {
            if (!string.IsNullOrEmpty(url))
            {
                return url;
            }
            else if (string.IsNullOrEmpty(call_index))
            {
                return linkurl(_key, id);
            }
            return linkurl(_key, call_index);
        }
        #endregion

        /// <summary>
        /// 根据站点目录和已生成的链接重新组合(实际访问页面用到)
        /// </summary>
        /// <param name="sitepath">站点目录</param>
        /// <param name="urlpath">URL链接</param>
        /// <returns>String</returns>
        public string getlink(string sitepath, string urlpath)
        {
            if (string.IsNullOrEmpty(sitepath) || string.IsNullOrEmpty(urlpath))
            {
                return urlpath;
            }
            string requestDomain = System.Web.HttpContext.Current.Request.Url.Authority.ToLower(); //获取来源域名含端口号
            Dictionary<string, string> dic = SiteDomains.GetSiteDomains().Paths; //获取站点键值对
            //如果当前站点为默认站点则直接返回
            if (SiteDomains.GetSiteDomains().DefaultPath == sitepath.ToLower())
            {
                return urlpath;
            }
            //如果当前域名存在于域名列表则直接返回
            if (dic.ContainsKey(sitepath.ToLower()) && dic.ContainsValue(requestDomain))
            {
                return urlpath;
            }
            int indexNum = config.webpath.Length; //安装目录长度
            if (urlpath.StartsWith(config.webpath))
            {
                urlpath = urlpath.Substring(indexNum);
            }
            //安装目录+站点目录+URL
            return config.webpath + sitepath.ToLower() + "/" + urlpath;
        }

        /// <summary>
        /// 返回分页字符串
        /// </summary>
        /// <param name="pagesize">页面大小</param>
        /// <param name="pageindex">当前页</param>
        /// <param name="totalcount">记录总数</param>
        /// <param name="_key">URL映射Name名称</param>
        /// <param name="_params">传输参数</param>
        public string get_page_link(int pagesize, int pageindex, int totalcount, string _key, params object[] _params)
        {
            return Utils.OutPageList(pagesize, pageindex, totalcount, linkurl(_key, _params), 8);
        }

        /// <summary>
        /// 返回分页字符串
        /// </summary>
        /// <param name="pagesize">页面大小</param>
        /// <param name="pageindex">当前页</param>
        /// <param name="totalcount">记录总数</param>
        /// <param name="linkurl">链接地址</param>
        public string get_page_link(int pagesize, int pageindex, int totalcount, string linkurl)
        {
            return Utils.OutPageList(pagesize, pageindex, totalcount, linkurl, 8);
        }

        /// <summary>
        /// 返回分页字符串(支持语言选择)
        /// </summary>
        /// <param name="language">语言 cn中文、en英语</param>
        /// <param name="pagesize">页面大小</param>
        /// <param name="pageindex">当前页</param>
        /// <param name="totalcount">记录总数</param>
        /// <param name="_key">URL映射Name名称</param>
        /// <param name="_params">传输参数</param>
        public string get_page_link(string language, int pagesize, int pageindex, int totalcount, string _key, params object[] _params)
        {
            return Utils.OutPageList(pagesize, pageindex, totalcount, linkurl(_key, _params), 8, language);
        }

        /// <summary>
        /// 返回分页字符串(支持语言选择)
        /// </summary>
        /// <param name="language">语言 cn中文、en英语</param>
        /// <param name="pagesize">页面大小</param>
        /// <param name="pageindex">当前页</param>
        /// <param name="totalcount">记录总数</param>
        /// <param name="linkurl">链接地址</param>
        public string get_page_link(string language, int pagesize, int pageindex, int totalcount, string linkurl)
        {
            return Utils.OutPageList(pagesize, pageindex, totalcount, linkurl, 8, language);
        }
        #endregion

        #region 辅助方法(私有)========================================
        /// <summary>
        /// 获取当前页面包含的站点目录
        /// </summary>
        private string GetFirstPath(string requestPath)
        {
            int indexNum = config.webpath.Length; //安装目录长度
            //如果包含安装目录和aspx目录也要过滤掉
            if (requestPath.StartsWith(config.webpath + DTKeys.DIRECTORY_REWRITE_MVC + "/"))
            {
                indexNum = (config.webpath + DTKeys.DIRECTORY_REWRITE_MVC + "/").Length;
            }
            string requestFirstPath = requestPath.Substring(indexNum);
            if (requestFirstPath.IndexOf("/") > 0)
            {
                requestFirstPath = requestFirstPath.Substring(0, requestFirstPath.IndexOf("/"));
            }
            if (requestFirstPath != string.Empty && SiteDomains.GetSiteDomains().Paths.ContainsKey(requestFirstPath))
            {
                return requestFirstPath;
            }
            return string.Empty;
        }

        /// <summary>
        /// 获取链接的前缀
        /// </summary>
        /// <param name="requestPath">当前的URL地址</param>
        /// <param name="requestDomain">获得来源域名含端口号</param>
        /// <returns>String</returns>
        private string GetLinkStartString(string requestPath, string requestDomain)
        {
            string requestFirstPath = GetFirstPath(requestPath);//获得二级目录(不含站点安装目录)

            //检查是否与绑定的域名或者与默认频道分类的目录匹配
            if (SiteDomains.GetSiteDomains().Paths.ContainsValue(requestDomain))
            {
                return "/";
            }

            else if (requestFirstPath == string.Empty || requestFirstPath == SiteDomains.GetSiteDomains().DefaultPath)
            {
                return config.webpath;
            }
            else
            {
                return config.webpath + requestFirstPath + "/";
            }
        }

        /// <summary>
        /// 获取站点的目录
        /// </summary>
        /// <param name="requestPath">获取的页面，包含目录</param>
        /// <param name="requestDomain">获取的域名(含端口号)</param>
        /// <returns>String</returns>
        private string GetSitePath(string requestPath, string requestDomain)
        {
            //当前域名是否存在于站点目录列表
            if (SiteDomains.GetSiteDomains().Paths.ContainsValue(requestDomain))
            {
                string build_path = SiteDomains.GetSiteDomains().Domains[requestDomain];
                return GetSiteIsPC(build_path);
            }
            // 获取当前页面包含的站点目录
            string pagePath = GetFirstPath(requestPath);
            if (pagePath != string.Empty)
            {
                return pagePath;
            }
            string DefaultPath = SiteDomains.GetSiteDomains().DefaultPath;
            return GetSiteIsPC(DefaultPath);
        }

        /// <summary>
        /// 判断是手机访问、PC访问、微信浏览器访问
        /// </summary>
        /// <param name="build_path"></param>
        /// <returns></returns>
        private string GetSiteIsPC(string build_path)
        {
            var list = SiteDomains.GetSiteDomains().SiteList;
            if (list.Count == 1)//当只有一个站点时 返回传入站点
            {
                return build_path;
            }
            int siteId = list.Find(p => p.build_path == build_path).id;//找到当前模板的站点
            if (Utils.IsWeChat())//判断微信
            {
                var micro = SiteDomains.GetSiteDomains().SiteList.Find(p => p.site_type == 3 && p.inherit_id == siteId);//查找有无微信站点并且要继承
                if (micro != null)
                {
                    return micro.build_path;
                }
                //是微信访问但是没有微信站点只有手机站点 默认使用手机站点
                micro = SiteDomains.GetSiteDomains().SiteList.Find(p => p.site_type == 2 && p.inherit_id == siteId);//查找有无手机站点并且要继承
                if (micro != null)
                {
                    return micro.build_path;
                }
            }
            if (Utils.IsMobile())//判断手机端访问
            {
                var wap = SiteDomains.GetSiteDomains().SiteList.Find(p => p.site_type == 2 && p.inherit_id == siteId);//查找有无手机站点并且要继承
                if (wap != null)
                {
                    return wap.build_path;
                }
            }
            return build_path;
        }

        /// <summary>
        /// 参数个数是否匹配
        /// </summary>
        private bool IsUrlMatch(Model.url_rewrite_item item, params object[] _params)
        {
            int strLength = 0;
            if (!string.IsNullOrEmpty(item.querystring))
            {
                strLength = item.querystring.Split('&').Length;
            }
            if (strLength == _params.Length)
            {
                //注意__id__代表分页页码，所以须替换成数字才成进行匹配
                if (Regex.IsMatch(string.Format(item.path, _params).Replace("__id__", "1"), item.pattern, RegexOptions.None | RegexOptions.IgnoreCase))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 替换扩展名
        /// </summary>
        private string GetUrlExtension(string urlPage, string staticExtension)
        {
            return Utils.GetUrlExtension(urlPage, staticExtension);
        }

        #endregion

        #region 会员用户方法==========================================
        /// <summary>
        /// 判断用户是否已经登录(解决Session超时问题)
        /// </summary>
        public bool IsUserLogin()
        {
            //如果Session为Null
            if (System.Web.HttpContext.Current.Session[DTKeys.SESSION_USER_INFO] != null)
            {
                return true;
            }
            else
            {
                //检查Cookies
                string username = Utils.GetCookie(DTKeys.COOKIE_USER_NAME_REMEMBER, "DTcms");
                string password = Utils.GetCookie(DTKeys.COOKIE_USER_PWD_REMEMBER, "DTcms");
                if (username != "" && password != "")
                {
                    BLL.users bll = new BLL.users();
                    Model.users model = bll.GetModel(username, password, 0, 0, false);
                    if (model != null)
                    {
                        System.Web.HttpContext.Current.Session[DTKeys.SESSION_USER_INFO] = model;
                        return true;
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// 取得用户信息
        /// </summary>
        public Model.users GetUserInfo()
        {
            if (IsUserLogin())
            {
                Model.users model = System.Web.HttpContext.Current.Session[DTKeys.SESSION_USER_INFO] as Model.users;
                if (model != null)
                {
                    //为了能查询到最新的用户信息，必须查询最新的用户资料
                    model = new BLL.users().Get(model.id);
                    return model;
                }
            }
            return null;
        }

        /// <summary>
        /// 取得用户信息
        /// </summary>
        public Model.users GetUserInfo(int uid)
        {
            Model.users model = new BLL.users().Get(uid);
            return model;
        }
        #endregion
    }
}
